#include "PhysicsContext.hpp"

namespace zen {

	namespace physics {


		PhysicsContext::PhysicsContext() {
			this->id = -1;
			this->broadphase = new btDbvtBroadphase();
			this->collisionConfiguration = new btDefaultCollisionConfiguration();
			this->collisionDispatcher = new btCollisionDispatcher(this->collisionConfiguration);
			this->constraintSolver = new btSequentialImpulseConstraintSolver;
			this->dynamicsWorld = new btDiscreteDynamicsWorld(this->collisionDispatcher, this->broadphase, this->constraintSolver, this->collisionConfiguration);
			this->dynamicsWorld->setGravity(btVector3(0.0f, 0.0f, -9.78f));
		}

		PhysicsContext::~PhysicsContext() {
			delete this->dynamicsWorld;
			delete this->constraintSolver;
			delete this->collisionDispatcher;
			delete this->collisionConfiguration;
			delete this->broadphase;
		}

		bool PhysicsContext::addStaticPlane(const glm::mat4 &view, const float &originDistance, const glm::vec3 &normal) {
			btStaticPlaneShape* shape = new btStaticPlaneShape(zen::utils::BulletConvert::toBtVector3(normal), originDistance);
			btScalar mass = 0.0;
			btVector3 localInertia(0.0, 0.0, 0.0);
			btTransform transform = zen::utils::BulletConvert::toBtTransform(view);
			btDefaultMotionState* motionState = new btDefaultMotionState(transform);
			btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo(mass, motionState, shape, localInertia);
			btRigidBody* body = new btRigidBody(rigidBodyConstructionInfo);
			return addRigidBody(body);
		}

		bool PhysicsContext::addBox(const glm::mat4 &view, const glm::vec3 &halfExtents) {
			btBoxShape* shape = new btBoxShape(zen::utils::BulletConvert::toBtVector3(halfExtents));
			btScalar mass = 1.0;
			btVector3 localInertia(0.0, 0.0, 0.0);
			shape->calculateLocalInertia(mass, localInertia);
			btTransform transform = zen::utils::BulletConvert::toBtTransform(view);
			btDefaultMotionState* motionState = new btDefaultMotionState(transform);
			btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo(mass, motionState, shape, localInertia);
			btRigidBody* body = new btRigidBody(rigidBodyConstructionInfo);
			return addRigidBody(body);
		}

	} // namespace physics

} // namespace zen
